﻿using Microsoft.VisualBasic.Devices;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MarkDownFileSplitter.Meilisearch
{
    public partial class AddDocumentControl : UserControl
    {
        private DataParser m_dataParser = new DataParser();

        private string? m_indexUid = null;
        private string? m_primaryKey = null;

        public bool IsNewIndex { get; set; } = true;

        public AddDocumentControl()
        {
            InitializeComponent();
        }

        public void SetIndexSetting(string indexUid, string primaryKey, List<string> attributeNames)
        {
            m_indexUid = indexUid;
            m_primaryKey = primaryKey;

            //如果已上传过document，则需要禁用这些设置
            bool neverUploadDocument = attributeNames.Count == 0;
            //bool neverUploadDocument = true;
            /*this.checkedListBox_uploadFields.Enabled = neverUploadDocument;
            this.checkBox_autoGenerateId.Enabled = neverUploadDocument;
            this.button_allSelect.Enabled = neverUploadDocument;
            this.button_antiSelect.Enabled = neverUploadDocument;*/

            if (!IsNewIndex)
            {
                this.comboBox_idAttr.Items.Clear();
                if (!neverUploadDocument)
                {
                    this.comboBox_idAttr.Items.Add(m_primaryKey);//DropDownStyle改为DropDownList后，需要添加该项才能设置对应文字
                    this.comboBox_idAttr.Text = m_primaryKey;
                }
            }
            this.comboBox_idAttr.Enabled = neverUploadDocument;

            this.textBox_indexName.Text = indexUid;
            this.textBox_indexName.Enabled = false;

            //切换Index时还需要清空界面，不然可能会导致别的问题
            this.dataGridView_dataPreview.DataSource = null;
            this.checkedListBox_uploadFields.Items.Clear();
        }

        #region 打开数据源、导入数据
        private void 导入文档ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "JSON Files|*.json";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                List<dynamic> parseResult = m_dataParser.Parse(openFileDialog.FileName);

                if (parseResult.Count == 0)
                {
                    MessageBox.Show("Json文件格式不符合要求，未解析出有效数据");
                    return;
                }

                InitFromFile(parseResult, Path.GetFileNameWithoutExtension(openFileDialog.FileName));
            }
        }

        private void 导入sqliteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormOpenSqlite form = new FormOpenSqlite() { StartPosition = FormStartPosition.CenterParent };
            if (form.ShowDialog() == DialogResult.OK)
            {
                List<dynamic> parseResult = m_dataParser.Parse(form.Result);
                InitFromFile(parseResult, form.TableName);
            }
        }
        private void 从Pg数据库中导入ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormOpenPG form = new FormOpenPG() { StartPosition = FormStartPosition.CenterParent };
            if (form.ShowDialog() == DialogResult.OK)
            {
                List<dynamic> parseResult = m_dataParser.Parse(form.Result, form.ColumnType);
                InitFromFile(parseResult, form.TableName);
            }
        }
        #endregion


        #region 注入数据
        private void InitFromFile(List<dynamic> parseResult, string tableName)
        {
            var propertyNames = m_dataParser.GetAllPropertyNames();

            this.checkedListBox_uploadFields.Items.Clear();
            this.comboBox_idAttr.Items.Clear();
            foreach (string name in propertyNames)
            {
                this.checkedListBox_uploadFields.Items.Add(name);
                this.comboBox_idAttr.Items.Add(name);
            }
            //自动勾选Id字段
            for (int i = 0; i < this.checkedListBox_uploadFields.Items.Count; i++)
            {
                if (this.checkedListBox_uploadFields.Items[i].ToString() == m_primaryKey)
                {
                    this.checkedListBox_uploadFields.SetItemChecked(i, true);
                    break;
                }
            }

            if (IsNewIndex)
            {
                this.textBox_indexName.Text = tableName;
                this.checkBox_autoGenerateId.Enabled = true;
                if (this.comboBox_idAttr.Items.Count > 0)
                    this.comboBox_idAttr.SelectedIndex = 0;
            }
            else
            {
                this.comboBox_idAttr.Text = m_primaryKey;
            }

            // 暂时禁用表格刷新以提高性能
            this.dataGridView_dataPreview.SuspendLayout();

            if (m_dataParser.SourceDataTable == null)
            {
                DataTable dt = new DataTable();

                // 如果没有数据则返回
                if (parseResult == null || parseResult.Count == 0)
                    return;

                // 获取第一个结果对象用于创建列
                var firstResult = parseResult.First();
                var properties = firstResult.Properties();

                // 创建列
                foreach (var prop in properties)
                {
                    dt.Columns.Add(prop.Name);
                }

                // 添加数据行
                int rowsCount = 0;
                foreach (var result in parseResult)
                {
                    var rowValues = new List<object>();
                    foreach (var prop in properties)
                    {
                        rowValues.Add(result.GetValue(prop.Name));
                    }
                    dt.Rows.Add(rowValues.ToArray());
                    rowsCount++;
                    if (rowsCount > 100)
                    {
                        break;
                    }
                }
                this.dataGridView_dataPreview.DataSource = dt;
            }
            else
            {
                DataTable dt = new DataTable();
                for (var i = 0; i < m_dataParser.SourceDataTable.Columns.Count; i++)
                {
                    dt.Columns.Add(m_dataParser.SourceDataTable.Columns[i].Clone());
                }
                for (var i = 0; i < 100 && i < m_dataParser.SourceDataTable.Rows.Count; i++)
                {
                    dt.Rows.Add(m_dataParser.SourceDataTable.Rows[i].ItemArray.ToArray());
                }
                this.dataGridView_dataPreview.DataSource = dt;
            }

            // 恢复表格刷新并调整列宽
            this.dataGridView_dataPreview.ResumeLayout();
            this.dataGridView_dataPreview.AutoResizeColumns();

            for (var i = 0; i < this.dataGridView_dataPreview.Columns.Count; i++)
            {
                if (this.dataGridView_dataPreview.Columns[i].Width > 300)
                {
                    this.dataGridView_dataPreview.Columns[i].Width = 300;
                }
            }
        }

        #endregion

        private void button_allSelect_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < this.checkedListBox_uploadFields.Items.Count; i++)
            {
                this.checkedListBox_uploadFields.SetItemChecked(i, true);
            }
        }

        private void button_antiSelect_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < this.checkedListBox_uploadFields.Items.Count; i++)
            {
                this.checkedListBox_uploadFields.SetItemChecked(i, false);
            }
        }

        private async void button_upload_Click(object sender, EventArgs e)
        {
            if (this.textBox_indexName.Text=="")
            {
                MessageBox.Show("Index名字不能为空！");
                return;
            }
            if (Regex.IsMatch(this.textBox_indexName.Text, "[\u2E80-\u9FFF]"))
            {
                MessageBox.Show("Index名字包含中文，无法上传");
                return;
            }
            if (string.IsNullOrEmpty(this.comboBox_idAttr.Text))
            {
                MessageBox.Show("主键字段为空，无法上传");
                return;
            }
            if (this.checkedListBox_uploadFields.CheckedItems.Count == 0)
            {
                MessageBox.Show("未勾选任何字段，无法上传");
                return;
            }

            m_dataParser.AutoGenId = this.checkBox_autoGenerateId.Checked;

            if (IsNewIndex)
            {
                if (!IsPrimaryKeyIsChecked())
                {
                    return;
                }
                m_indexUid = this.textBox_indexName.Text;
                m_primaryKey = this.comboBox_idAttr.Text;
                if (!await CreateIndex())
                {
                    return;
                }
                // 新索引时，起始ID从0开始
                m_dataParser.StartIdOffset = 0;
            }
            else
            {
                if (this.checkBox_autoGenerateId.Checked)
                {
                    //自动生成的字段固定为"Id"
                    if (m_primaryKey != "Id")
                    {
                        MessageBox.Show("需要按序号补充的Index的Id字段名必须为\"Id\"");
                        return;
                    }
                    
                    // 补充模式：获取现有索引的最大ID值
                    try
                    {
                        UpdateStatusText("正在获取现有索引的最大ID值...");
                        int maxId = await MeilisearchUploader.Instance.GetMaxIdValue(m_indexUid);
                        m_dataParser.StartIdOffset = maxId + 1; // 从最大ID+1开始
                        UpdateStatusText($"将从ID {m_dataParser.StartIdOffset} 开始补充数据");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"获取最大ID值失败：{ex.Message}");
                        return;
                    }
                }
                else
                {
                    if (!IsPrimaryKeyIsChecked())
                    {
                        return;
                    }
                    // 非自动生成ID的补充模式，起始偏移量为0
                    m_dataParser.StartIdOffset = 0;
                }
            }

            //存储选中字段
            List<string> checkedItems = new List<string>();
            foreach (var item in this.checkedListBox_uploadFields.CheckedItems)
            {
                checkedItems.Add(item.ToString());
            }
            if (checkedItems.Count == checkedListBox_uploadFields.Items.Count)
            {
                checkedItems = null;
            }

            int batchNum = 100;//每个批次的文档数量
            int batchCount = (int)Math.Ceiling(m_dataParser.Items.Count / (double)batchNum);

            // 设置进度条最大值和初始值
            this.progressBar.Maximum = batchCount;
            this.progressBar.Value = 0;

            for (int i = 0; i < batchCount; i++)
            {
                UpdateStatusText($"正在上传第{i + 1}/{batchCount}批次");

                JArray dataArr = m_dataParser.ConvertToJArray(checkedItems, i * batchNum, (i + 1) * batchNum);
                if (dataArr.Count == 0)
                {
                    MessageBox.Show("数据为空，无法上传");
                    break;
                }
                await MeilisearchUploader.Instance.AddOrUpdateDocuments(dataArr, m_indexUid);

                // 更新进度条
                this.progressBar.Value = i + 1;
            }

            MessageBox.Show("上传成功");
            UpdateStatusText("上传成功");

            if (IsNewIndex)
                this.ParentForm?.Close();
        }

        private async Task<bool> CreateIndex()
        {
            List<string> existedIndexNames = IndexTreeView.GetExistedIndexNames();
            if (existedIndexNames.Contains(m_indexUid))
            {
                MessageBox.Show("该Index已存在!请修改IndexUid!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            var result = await MeilisearchUploader.Instance.CreateIndex(m_indexUid, m_primaryKey);
            //等待创建Index完成
            await MeilisearchUploader.Instance.IsTaskSuccess(result["taskUid"].ToString(), 100, true);
            var node = new TreeNode(m_indexUid);
            node.Tag = new IndexInfo(m_indexUid, m_primaryKey);
            IndexTreeView.AddTreeNode(node);
            return true;
        }

        private bool IsPrimaryKeyIsChecked()
        {
            // 检查主键是否在选中的字段中
            bool isPrimaryKeyInCheckedItems = false;
            foreach (var item in this.checkedListBox_uploadFields.CheckedItems)
            {
                if (item.ToString() == m_primaryKey)
                {
                    isPrimaryKeyInCheckedItems = true;
                    break;
                }
            }
            if (!isPrimaryKeyInCheckedItems)
            {
                MessageBox.Show($"主键字段 {m_primaryKey} 必须包含在选中的字段中");
                return false;
            }
            return true;
        }

        private void UpdateStatusText(string statusText)
        {
            int statusTextStartIndex = this.label_uploadStatus.Text.IndexOf("：") + 1;
            this.label_uploadStatus.Text = this.label_uploadStatus.Text.Substring(0, statusTextStartIndex) + statusText;
        }

        private void checkBox_autoGenerateId_CheckedChanged(object? sender, EventArgs e)
        {
            if (!IsNewIndex)
                return;
            if (this.checkBox_autoGenerateId.Checked)
            {
                //勾选的话需要在comboBox和checkBoxList中添加"Id"字段
                foreach (string item in this.comboBox_idAttr.Items)
                {
                    //检查是否已存在，存在的话不允许勾选
                    if (item == "Id")
                    {
                        MessageBox.Show("当前已存在名为\"Id\"的字段，不允许自动添加");
                        this.checkBox_autoGenerateId.CheckedChanged -= checkBox_autoGenerateId_CheckedChanged;
                        this.checkBox_autoGenerateId.Checked = false;
                        this.checkBox_autoGenerateId.CheckedChanged += checkBox_autoGenerateId_CheckedChanged;

                        return;
                    }
                }
                this.comboBox_idAttr.Items.Insert(0, "Id");
                this.comboBox_idAttr.SelectedIndex = 0;
                this.checkedListBox_uploadFields.Items.Insert(0, "Id");
                this.checkedListBox_uploadFields.SetItemChecked(0, true);
            }
            else
            {
                //移除自动添加的"Id"字段
                if (this.comboBox_idAttr.Items.Count > 0 && this.comboBox_idAttr.Items[0] == "Id")
                {
                    this.comboBox_idAttr.Items.RemoveAt(0);
                    this.comboBox_idAttr.SelectedIndex = 0;
                }
                if (this.checkedListBox_uploadFields.Items.Count > 0 && this.checkedListBox_uploadFields.Items[0] == "Id")
                {
                    this.checkedListBox_uploadFields.Items.RemoveAt(0);
                }
            }
        }

        private void comboBox_idAttr_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_primaryKey = this.comboBox_idAttr.Text;
        }

        private void button1_ClickAsync(object sender, EventArgs e)
        {
            m_primaryKey = this.comboBox_idAttr.Text;
            var result = MeilisearchUploader.Instance.UpdatePrimaryKey(m_indexUid, m_primaryKey);
            MessageBox.Show("已经提交");
        }
    }
}
